package com.car.loan.project.xr.controller;

import com.car.loan.framework.web.domain.AjaxResult;
import com.car.loan.project.xr.service.IndexService;
import com.car.loan.project.xr.util.bo.business.IndexBaseQuery;
import com.car.loan.project.xr.util.vo.IndexBaseDataVo;
import com.car.loan.project.xr.util.vo.IndexData;
import com.car.loan.project.xr.util.vo.IndexDataVo;
import com.car.loan.project.xr.util.vo.IndexStatusDataVo;
import com.google.common.collect.Lists;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author huangding
 * @date 2020/3/6 14:03
 */
@RestController
@RequestMapping("index")
@Api(value = "主页管理", tags = "主页管理")
public class IndexController {


    @Autowired
    private IndexService indexService;

    @GetMapping("base")
    @ApiOperation(value = "获取最上面基础数据", notes = "今日提交、今日付款、本月付款、本月放贷；分别统计、个数、分期金额、融资金额", response = IndexBaseDataVo.class)
    public AjaxResult base() {
        IndexBaseDataVo indexBaseDataVo = new IndexBaseDataVo();
        String nowadaysBusinessSqlQuery =
            " ls.business_status = 1 AND ls.business_time>='" + LocalDate.now().toString()
                + "' AND ls.business_time<='" + LocalDate.now().plusDays(1).toString() + "'";
        indexBaseDataVo.setNowadaysBusiness(getIndexData(nowadaysBusinessSqlQuery));

        //今天付款数据
        String nowadaysPaymentSqlQuery =
            "ls.payment_info_status = 1 AND de.advance_date >='" + LocalDate.now().toString()
                + "' AND de.advance_date <='" + LocalDate.now().plusDays(1).toString() + "'";
        indexBaseDataVo.setNowadaysPayment(getIndexData(nowadaysPaymentSqlQuery));

        //本月付款
        String monthPaymentSqlQuery =
            "ls.payment_info_status = 1 AND de.advance_date >='" + LocalDate.now()
                .withDayOfMonth(1).toString()
                + "' AND de.advance_date <='" + LocalDate.now().plusDays(1).toString() + "'";
        indexBaseDataVo.setMonthPayment(getIndexData(monthPaymentSqlQuery));

        //本月放贷
        String monthLendSqlQuery =
            "ls.make_loans_info_status = 1 AND de.lend_date >='" +
                LocalDate.now()
                    .withDayOfMonth(1).toString()
                + "' AND de.lend_date<='" + LocalDate.now().plusDays(1).toString() + "'";

        indexBaseDataVo.setMonthLend(getIndexData(monthLendSqlQuery));
        return AjaxResult.success(indexBaseDataVo);
    }

    @GetMapping("lend")
    @ApiOperation(value = "获取放贷数据", notes = "统计近6个月，不包括本月的银行放贷（分期金额、融资金额）", response = IndexLendData.class, responseContainer = "list")
    public AjaxResult lend() {
        int queryDateCount = 6;
        //添加空白日期
        LocalDate localDate = LocalDate.now().minusMonths(6)
            .withDayOfMonth(1);
        String monthLendSqlQuery =
            "ls.make_loans_info_status = 1 AND de.lend_date >='" +
                localDate.toString()
                + "' AND de.lend_date <='" + LocalDate.now().minusMonths(1)
                .with(TemporalAdjusters.lastDayOfMonth()).toString() + "'";

        List<IndexData> baseByQuery = getBaseByQuery(monthLendSqlQuery);
        Map<String, List<IndexData>> collect =
            baseByQuery.stream()
                .peek(indexData -> indexData.setLendDate(indexData.getLendDate().substring(0, 7)))
                .collect(Collectors.groupingBy(IndexData::getLendDate));

        if (collect.size() != queryDateCount) {
            for (int i = 0; i < queryDateCount; i++) {
                String substring = localDate.plusMonths(i).toString().substring(0, 7);
                collect.putIfAbsent(substring, Lists.newArrayList());
            }
        }
        List<IndexLendData> indexLendDataList = new ArrayList<>(collect.size());
        collect.forEach((key, val) -> {
            IndexLendData indexLendData = new IndexLendData();
            indexLendData.setLendDate(key);
            indexLendData.setInstallmentAmount(
                val.stream().mapToDouble(IndexData::getInstallmentAmount).sum());
            indexLendData.setFinancingAmount(
                val.stream().mapToDouble(IndexData::getFinancingAmount).sum());
            indexLendDataList.add(indexLendData);
        });
        indexLendDataList.sort(Comparator.comparing(IndexLendData::getLendDate));
        return AjaxResult.success(indexLendDataList);
    }

    @Data
    private static class IndexLendData {

        @ApiModelProperty("放贷时间")
        private String lendDate;

        @ApiModelProperty("分期金额")
        private Double installmentAmount = 0D;

        @ApiModelProperty("融资金额")
        private Double financingAmount = 0D;

    }

    @GetMapping("statusData")
    @ApiOperation(value = "获取各种状态数据", response = IndexStatusDataVo.class)
    public AjaxResult getStatusData() {
        IndexStatusDataVo indexStatusDataVo = new IndexStatusDataVo();
        // 待审批（业务已提交，审批未完成，需加签的加签审批未完成）、
        String businessSql = " ls.business_status = 1 AND (ls.business_audit_status = 0 OR (ls.business_audit_status = 4  and ls.business_apostille_status = 0)) ";
        indexStatusDataVo.setBusiness(getIndexData(businessSql));
        // 待付款（审批已完成，需加签的加签审批已完成，付款信息未提交）、
        String paymentSql = " ls.payment_info_status = 0 AND (ls.business_audit_status = 1 OR (ls.business_audit_status = 4  and ls.business_apostille_status = 1)) ";
        indexStatusDataVo.setPayment(getIndexData(paymentSql));
        // 已垫款（付款信息已提交，放贷信息未提交）、
        String advanceSql = " ls.payment_info_status = 1 AND ls.make_loans_info_status = 0 ";
        indexStatusDataVo.setAdvance(getIndexData(advanceSql));
        // 待放贷（合同审核已提交，放贷信息未提交）、
        String lendSql = " ls.contract_audit_status = 1 AND ls.make_loans_info_status = 0 ";
        indexStatusDataVo.setLend(getIndexData(lendSql));
        // 待上牌（付款信息已提交，牌证信息未提交）、
        String licenseSql = " ls.payment_info_status = 1 AND ls.license_info_status = 0 ";
        indexStatusDataVo.setLicense(getIndexData(licenseSql));
        // 待抵押（放贷信息已提交，抵押信息未提交）
        String mortgageSql = " ls.mortgage_info_status = 0 AND ls.make_loans_info_status = 1 ";
        indexStatusDataVo.setMortgage(getIndexData(mortgageSql));
        // 资料超期：付款信息己提交，资料审核未提交，且当前日期-付款日期>1(付款日期小于昨天)
        LocalDate now = LocalDate.now();
        String dataExpiredSql =
            " ls.data_audit_status = 0  AND ls.payment_info_status = 1  AND de.advance_date < '" + now.minusDays(1).toString() + "'";
        indexStatusDataVo.setDataExpired(getIndexData(dataExpiredSql));
        //抵押超期：放贷信息己提交，抵押信息未提交，且当前日期-放贷日期>30
        String mortgageExpiredSql =
            " ls.make_loans_info_status = 1 AND ls.mortgage_info_status = 0  AND de.lend_date < '"
                + now.minusDays(30).toString() + "'";
        indexStatusDataVo.setMortgageExpired(getIndexData(mortgageExpiredSql));
        return AjaxResult.success(indexStatusDataVo);
    }

    private List<IndexData> getBaseByQuery(String query) {
        IndexBaseQuery indexBaseQuery = new IndexBaseQuery();
        indexBaseQuery.setQuery(query);
        return indexService.getBaseByQuery(indexBaseQuery);
    }


    private IndexDataVo getIndexData(String query) {
        List<IndexData> baseByQuery = getBaseByQuery(query);
        if (null != baseByQuery && baseByQuery.size() > 0) {
            IndexDataVo indexDataVo = new IndexDataVo();
            indexDataVo.setCount(baseByQuery.size());
            indexDataVo.setInstallmentAmount(
                baseByQuery.stream().mapToDouble(IndexData::getInstallmentAmount).sum());
            indexDataVo.setFinancingAmount(
                baseByQuery.stream().mapToDouble(IndexData::getFinancingAmount).sum());
            return indexDataVo;
        }
        return new IndexDataVo();
    }

}
